home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- organization: Delft University of Technology, Dep. of Electrotechnical engineering.
- subject: v10i047: weekday: gives info on dates: like weeknr and weekday
- From: marcel@duteca.tudelft.nl (Marcel Mol)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 10, Issue 47
- Submitted-by: marcel@duteca.tudelft.nl (Marcel Mol)
- Archive-name: weekday.c
-
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #!/bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # weekday.c 26078 bytes
- # This archive created: Fri Jan 26 00:38:00 MET 1990
- # By: Marcel J.E. Mol
- export PATH
- echo shar: extracting weekday.c
- if test -f 'weekday.c'
- then
- echo shar: over-writing existing file "'weekday.c'"
- fi
- sed -e 's/^-//' << \_E_O_F_ > weekday.c
- -
- -/* @(#) weekday.c 3.31 09/01/90 */
- -/*************************************************************************
- - ** **
- - ** Name : weekday **
- - ** Author : Marcel J.E. Mol **
- - ** Date : 12/28/89 (first release) **
- - ** Version : 3.25 **
- - ** Files : weekday.c Main source file **
- - ** **
- - ** ------------------------- Revision List ------------------------- **
- - ** Ver Date Name Remarks **
- - ** 3.31 09/01/90 Marcel Mol Removed unnecessary code. **
- - ** Added comments. **
- - ** 3.30 08/01/90 Marcel Mol Improved option handling. **
- - ** verbose works on more options. **
- - ** use printf field length option to **
- - ** get short day and month names. **
- - ** 3.26 07/01/90 Marcel Mol Filled in usage function. **
- - ** 3.25 04/01/90 Marcel Mol Use 'today' when no date is given. **
- - ** 3.20 03/01/90 Marcel Mol Allow bsd `date` as input. **
- - ** 3.11 03/01/90 Marcel Mol Documentation, typos, checkdate(). **
- - ** Removed redundant checks. **
- - ** 3.10 02/01/90 Marcel Mol Added -s and -v options. **
- - ** allow yy.ddd input and implement **
- - ** julian date conversion. **
- - ** 3.00 12/30/89 Marcel Mol Set up user interface. **
- - ** Allow mm/dd/yy and dd-mm-yy input. **
- - ** Options to print different parts. **
- - ** 2.10 12/28/89 Marcel Mol Added Julianday. **
- - ** 2.00 12/27/89 Marcel Mol Made weekday and weeknr everlasting.**
- - ** 1.00 12/26/89 Marcel Mol First release. **
- - ** Set up algorithms weekday weeknr. **
- - ** ================================================================= **
- - ** **
- - ** Compile as follows: cc weekday.c -Oso weekday **
- - ** **
- - ** Usage: weekday [-svdDmMywjnah] [<date>] **
- - ** **
- - ** Weekday outputs line on which it informs you about several **
- - ** thing of the given <date>. **
- - ** The <date> input may be in several formats: **
- - ** **
- - ** mm/dd/yy e.g. 10/30/89 or 1/2/510 **
- - ** dd-mm-yy e.g. 30-10-89 or 2-1-510 **
- - ** yy.ddd e.g. 89.303 or 510.2 **
- - ** `date` output e.g. Mon Oct 30 99:99:99 1989 **
- - ** **
- - ** If no date argument is given, weekday uses the system date. **
- - ** When the year number is less than 100 and the string **
- - ** forming the year does not start with a 0, the year is **
- - ** converted to be in the current century. So 10/30/89 is **
- - ** actually 10/30/1989. If the real year 89 is wanted specify **
- - ** it as 10/30/089. (the current century is a constant in the **
- - ** source code. If this programs survives 1999 this constant **
- - ** must be changed, and the program recompiled.) **
- - ** Note: make sure that `date` output is passed as one **
- - ** argument, so enclose it with "s. **
- - ** **
- - ** The output, when no options are given, is something like **
- - ** this: **
- - ** **
- - ** 30 October 1989 is on a Monday on julian day 303 in week 44 **
- - ** **
- - ** or: **
- - ** **
- - ** 2 Januari 510 is on a Friday on julian day 2 in week 1 **
- - ** **
- - ** Depending on the options the output changes: **
- - ** **
- - ** -s toggle short form output: Monday -> Mon, June -> Jun **
- - ** and vice versa. **
- - ** -v toggle verbose output; removes 'is on a' etc. **
- - ** and vice versa. (Only has effect on the default case **
- - ** and on the -a option.) **
- - ** -d prints day of week number: 1 is Monday, 7 is Sunday **
- - ** -D gives day of week name, i.e Monday or Mon **
- - ** -m prints the month number **
- - ** -M outputs the month name, i.e. Januari or Jan **
- - ** -y outputs the year number **
- - ** -w gives the week number **
- - ** -j outputs the julian day number **
- - ** -n gives day of month **
- - ** -a gives everything it knows. Without the -s and -v **
- - ** options this outputs the same as the default case. **
- - ** In fact -a is just short for -nmyDjw. **
- - ** -h give a usage message **
- - ** **
- - ** All options that print something also print a space **
- - ** character (except -a). **
- - ** The options may come in any order and as many times as **
- - ** you like. The -s and -v options only have an effect on the **
- - ** options that follow them. **
- - ** When now option is given the -a option is default. **
- - ** The output is ended with newline **
- - ** Examples: **
- - ** **
- - ** % weekday -yjMdD 12/31/89 **
- - ** 89 365 December 7 Sunday **
- - ** **
- - ** % weekday -yjMsdD 12/31/89 **
- - ** 89 365 December 7 Sun **
- - ** **
- - ** % weekday -yjsMsdD 12/31/89 **
- - ** 89 365 Dec 7 Sunday **
- - ** **
- - ** % weekday -v 30/30/89 **
- - ** 30 Oct 1989 is on a Mon on julian day 303 in week 44 **
- - ** **
- - ** BUGS: the program assumes there have always been leap years **
- - ** so year 4 is a leap year as far as the program can tell... **
- - ** **
- - ** This software is copyrighted (c) 1989 1990 by M.J.E. Mol. **
- - ** This code or part of this code may be used by freeware, **
- - ** public domain or any other non-commercial product. I only ask **
- - ** you to give me credit for the used code in the documentation **
- - ** and in your source code. **
- - ** **
- - ** If you want to use this code or part of this code in your **
- - ** shareware or any other commercial product, I ask you to contact **
- - ** me so we can setup an arrangement for the use of the code or part **
- - ** of the code. **
- - ** **
- - ** In any case, I can not be held responsible for any damage this **
- - ** code or part of this code may cause you or anyone or anything **
- - ** else. **
- - ** **
- - ** Mail bugs to: email: marcel@duteca.tudelft.nl **
- - ** pmail: Marcel J.E. Mol **
- - ** Karel Doormanlaan 58 **
- - ** 2283AT Rijswijk **
- - ** The Netherlands (Holland) **
- - ** Phone: (+31) 070-3932390 **
- - ** Bankaccount: 36.89.35.922 (In the Netherlands) **
- - ** **
- - ************************************************************************/
- -
- -char * copyright = "@(#) weekday.c 3.31 09/01/90 (c) M.J.E. Mol";
- -#include <stdio.h>
- -#include <string.h>
- -#include <time.h>
- -
- -
- -#define CENTURY 1900 /* prefix for years */
- -#define LEAP(year) ((year%4 == 0) && (year%100 != 0) || (year%400 == 0))
- -
- -/*
- - * Global variables
- - */
- -
- -char *weekdays[8] = {"", "Monday", "Tuesday", "Wednesday", "Thursday",
- - "Friday", "Saterday", "Sunday"};
- -char days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- -int juldays[13] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
- -char *monthname[13] = {"", "Januari", "Februari", "March", "April",
- - "May", "June", "July", "August",
- - "September", "Oktober", "November", "December"};
- -
- -int shortflag = 0; /* short output of day and month name */
- -int verbose = 1; /* output in a 'sentence' */
- -char * progname;
- -
- -
- -/*
- - * function declarations
- - */
- -void main();
- -void scanmmddyy();
- -void scanddmmyy();
- -int scanjul();
- -int scandate();
- -int julianday();
- -void julian2day();
- -int weekday();
- -int weeknr();
- -void checkdate();
- -void usage();
- -
- -
- -void main(argc, argv)
- -int argc;
- -char **argv;
- -{
- - int year, month, day, week;
- - int wday = -1;
- - int jday = -1;
- - int opt, haveopt;
- - char *date;
- - extern int optind; /* For getopt */
- - extern char * optarg; /* For getopt */
- -
- - progname = *argv;
- - date = argv[argc-1];
- -
- - /*
- - * pick up the date argument and scan it
- - */
- - if (*date == '-' || argc == 1) /* no date, take current */
- - wday = scandate(NULL, &year, &month, &day);
- - else if (strchr(date, '/') != NULL) /* mm/dd/yy format date */
- - scanmmddyy(date, &year, &month, &day);
- - else if (strchr(date, '-') != NULL) /* dd-mm-yy format date */
- - scanddmmyy(date, &year, &month, &day);
- - else if (strchr(date, '.') != NULL) /* yyyy.ddd format date */
- - jday = scanjulian(date, &year, &month, &day);
- - else /* unix date output format */
- - wday = scandate(date, &year, &month, &day);
- -
- - /*
- - * get missing data
- - */
- - if (jday == -1)
- - jday = julianday(year, month, day);
- - if (wday == -1)
- - wday = weekday(year, month, day);
- - week = weeknr(year, month, day);
- -
- -
- - /*
- - * do the output that the user wants...
- - */
- - while ((opt = getopt(argc, argv, "svdDmMywjnah")) != EOF) {
- - switch (opt) {
- - case 's' : shortflag ^= 1;
- - break;
- - case 'v' : verbose ^= 1;
- - break;
- - case 'D' : printf("%s%.*s ",
- - verbose ? "is on a " : "",
- - shortflag ? 3 : 9 , weekdays[wday]);
- - haveopt = 1;
- - break;
- - case 'd' : printf("%s%d ", verbose ? "is weekday " : "", wday);
- - haveopt = 1;
- - break;
- - case 'm' : printf("%d ", month);
- - haveopt = 1;
- - break;
- - case 'M' : printf("%.*s ", shortflag ? 3 : 9, monthname[month]);
- - haveopt = 1;
- - break;
- - case 'y' : printf("%d ", year);
- - haveopt = 1;
- - break;
- - case 'w' : printf("%s%d ", verbose ? "in week " : "", week);
- - haveopt = 1;
- - break;
- - case 'j' : printf("%s%d ", verbose ? "on julian day " : "", jday);
- - haveopt = 1;
- - break;
- - case 'n' : printf("%d ", day);
- - haveopt = 1;
- - break;
- - case 'a' : if (verbose) {
- - printf("%d %.*s %d is on a %.*s ",
- - day, shortflag ? 3 : 9, monthname[month],
- - year, shortflag ? 3 : 9, weekdays[wday]);
- - printf("on julian day %d in week %d", jday, week);
- - }
- - else
- - printf("%d %.*s %d %.*s %d %d",
- - day, shortflag ? 3 : 9, monthname[month],
- - year, shortflag ? 3 : 9, weekdays[wday],
- - jday, week);
- - haveopt = 1;
- - break;
- - case 'h' : usage();
- - break;
- - default : fprintf(stderr,
- - "%s: use -h option for help\n", progname);
- - exit(1);
- - break;
- - }
- - }
- -
- -
- - if (!haveopt) {
- - if (verbose) {
- - printf("%d %.*s %d is on a %.*s ",
- - day, shortflag ? 3 : 9, monthname[month],
- - year, shortflag ? 3 : 9, weekdays[wday]);
- - printf("on julian day %d in week %d", jday, week);
- - }
- - else
- - printf("%d %.*s %d %.*s %d %d",
- - day, shortflag ? 3 : 9, monthname[month],
- - year, shortflag ? 3 : 9, weekdays[wday],
- - jday, week);
- - }
- -
- - /*
- - * finish with a newline
- - */
- - putchar('\n');
- -
- - exit(0);
- -
- -} /* main */
- -/*************************************************************************
- - ** **
- - ** DATE SCANNING ROUTINES **
- - ** **
- - *************************************************************************/
- -
- -/*
- - * scanmmddyy --- scan the date variable in the form MM/DD/YY.
- - * MM, DD and YY may be variable sized numbers.
- - * output is in output variables year, month and day.
- - */
- -void scanmmddyy(date, year, month, day)
- -char *date;
- -int *year, *month, *day;
- -{
- - char *i;
- -
- - if (sscanf(date, "%d/%d/%d", month, day, year) != 3 ||
- - *month <= 0 || *day <= 0 || *year < 0) {
- - fprintf(stderr, "%s: error in mm/dd/yy format date %s\n",
- - progname, date);
- - exit(4);
- - }
- -
- - if (*year < 100) {
- - i = strrchr(date, '/');
- - if (*i != 0)
- - *year += CENTURY;
- - }
- -
- - return;
- -
- -} /* scanmmddyy */
- -
- -
- -
- -/*
- - * scanddmmyy --- scan the date variable in the form DD-MM-YY.
- - * DD, MM and YY may be variable sized numbers.
- - * output is in output variables year, month and day.
- - */
- -void scanddmmyy(date, year, month, day)
- -char *date;
- -int *year, *month, *day;
- -{
- - char *i;
- -
- - if (sscanf(date, "%d-%d-%d", day, month, year) != 3 ||
- - *month <= 0 || *day <= 0 || *year < 0) {
- - fprintf(stderr, "%s: error in dd-mm-yy format date %s\n",
- - progname, date);
- - exit(4);
- - }
- -
- - if (*year < 100) {
- - i = strrchr(date, '-');
- - if (*i != 0)
- - *year += CENTURY;
- - }
- -
- - return;
- -
- -} /* scanddmmyy */
- -
- -
- -
- -/*
- - * scanjulian --- scan the date variable in the form YY.DDD.
- - * YY and DDD may be variable sized numbers.
- - * output is in output variables year, month and day.
- - * the return value is tha actual julian day DDD.
- - */
- -int scanjulian(date, year, month, day)
- -char *date;
- -int *year, *month, *day;
- -{
- - int jday;
- -
- - if (sscanf(date, "%d.%d", year, &jday) != 2 || *year < 0 || jday <= 0) {
- - fprintf(stderr, "%s: error in julian date %s\n", progname, date);
- - exit(4);
- - }
- -
- - if ((*year < 100) && (*date != '0'))
- - *year += CENTURY;
- - julian2day(*year, jday, month, day);
- -
- - return jday;
- -
- -} /* scanjulian */
- -
- -
- -
- -/*
- - * scandate --- scan the date variable in the Unix `date` form.
- - * This can look like: "Mon Jan 8 20:10:10 MET 1990"
- - * or: "Mon Jan 8 20:10:10 1990"
- - * the number of spaces between the fields is not fixed
- - * (although date output is always in the same with, see ctime(3).
- - * output is in output variables year, month and day.
- - * the return value is the day of the week number.
- - * If the date input is the NULL pointer, the xurrent system date
- - * is taken.
- - */
- -int scandate(date, year, month, day)
- -char *date;
- -int *year, *month, *day;
- -{
- - char *i;
- - char dayname[4];
- - char monname[10];
- - int j, k;
- - long tim;
- -
- - if (date == NULL) {
- - tim = time((long *) 0);
- - date= ctime(&tim);
- - }
- -
- - if (sscanf(date, "%3s %3s %d %*s %d", /* date without time zone */
- - dayname, monname, day, year) != 4 &&
- - sscanf(date, "%3s %3s %d %*s %*s %d", /* date with time zone */
- - dayname, monname, day, year) != 4) {
- - fprintf(stderr, "%s: error in unix `date` format date %s\n",
- - progname, date);
- - exit(4);
- - }
- -
- - for(j=1; j<12; j++) {
- - if (strncmp(monname, monthname[j], 3) == NULL)
- - break;
- - }
- - if (strncmp(monname, monthname[j], 3) != NULL) {
- - fprintf(stderr, "%s: error in unix `date` format date %s\n",
- - progname, date);
- - exit(4);
- - }
- - *month = j;
- - for(j=1; j<7; j++) {
- - if (strncmp(dayname, weekdays[j], 3) == NULL)
- - break;
- - }
- - if (strncmp(dayname, weekdays[j], 3) != NULL) {
- - fprintf(stderr, "%s: error in unix `date` format date %s\n",
- - progname, date);
- - exit(4);
- - }
- -
- - return j;
- -
- -} /* scandate */
- -/*************************************************************************
- - ** **
- - ** DATE CONVERSION ROUTINES **
- - ** **
- - *************************************************************************/
- -
- -
- -
- -/*
- - * julian2day -- converts year and julian day value to the corresponding
- - * month and day of the month values for that year.
- - * these values are returned in the ouput variables month and day.
- - */
- -void julian2day(year, jday, month, day)
- -int year, jday;
- -int *month, *day;
- -{
- - int leap;
- -
- - leap = LEAP(year) ? 1 : 0;
- - if (jday > 365+leap || jday <= 0) {
- - fprintf(stderr, "%s: error in julian date %d.%d\n",
- - progname, year, jday);
- - exit(8);
- - }
- -
- - if (jday <= 31) {
- - *month = 1;
- - *day = jday;
- - }
- - else if (jday <= 59+leap) {
- - *month = 2;
- - *day = jday - 31;
- - }
- - else if (jday <= 90+leap) {
- - *month = 3;
- - *day = jday - 59 - leap;
- - }
- - else if (jday <= 120+leap) {
- - *month = 4;
- - *day = jday - 90 - leap;
- - }
- - else if (jday <= 151+leap) {
- - *month = 5;
- - *day = jday - 120 - leap;
- - }
- - else if (jday <= 181+leap) {
- - *month = 6;
- - *day = jday - 151 - leap;
- - }
- - else if (jday <= 212+leap) {
- - *month = 7;
- - *day = jday - 181 - leap;
- - }
- - else if (jday <= 243+leap) {
- - *month = 8;
- - *day = jday - 212 - leap;
- - }
- - else if (jday <= 273+leap) {
- - *month = 9;
- - *day = jday - 243 - leap;
- - }
- - else if (jday <= 304+leap) {
- - *month = 10;
- - *day = jday - 273 - leap;
- - }
- - else if (jday <= 334+leap) {
- - *month = 11;
- - *day = jday - 304 - leap;
- - }
- - else {
- - *month = 12;
- - *day = jday - 334 - leap;
- - }
- -
- - return;
- -
- -} /* julian2day */
- -
- -
- -
- -/*
- - * julianday -- converts a year, mont and day value the corresponding julian
- - * day number of that year.
- - * the julian day is passed as a return value.
- - */
- -julianday(year, month, day)
- -int year, month, day;
- -{
- - register int doy;
- -
- - checkdate(year, month, day); /* exits if date in error */
- -
- - doy = juldays[month];
- - if ((month > 2) && LEAP(year))
- - doy++;
- - doy += day;
- -
- - return doy;
- -
- -} /* julianday */
- -
- -
- -
- -/*
- - * weekday -- returns the day of the week number based on the given
- - * year, month and day of the month value.
- - */
- -weekday(year, month, day)
- -int year, month, day;
- -{
- - register int dow;
- -
- - checkdate(year, month, day); /* exits if date in error */
- -
- - dow = 6 +
- - year + /* shift a day each year */
- - year/4 - year/100 + year/400 + /* shift a day each leap year */
- - juldays[month] + day;
- -
- - if ((month < 3) && LEAP(year)) /* first two months of leap don't */
- - dow--; /* have the extra leap shift */
- -
- - dow %= 7;
- - return (dow == 0) ? 7 : dow;
- -
- -} /* weekday */
- -
- -
- -/*
- - * weeknr -- returns the weeknumber of the given date (year, month and day of
- - * the month) for that year.
- - */
- -weeknr(year, month, day)
- -int year, month, day;
- -{
- - register int fday, jul, weeknum;
- -
- - checkdate(year, month, day); /* exits if date in error */
- -
- - fday = weekday(year, 1, 1);
- -
- - jul = julianday(year, month, day);
- - weeknum = (jul + fday - 2)/7;
- - if (fday <= 4)
- - weeknum++;
- -
- - if (weeknum == 0) /* go into previous year */
- - if ((fday == 5) || /* week 1 has 4 or 5 days and week */
- - ((fday == 6) && LEAP(year-1)) ) /* 53 has 4 or 5 days in year-1 */
- - return 53;
- - else
- - return 52;
- -
- - if (weeknum == 53) { /* only a week 53 if we have > 4 */
- - fday = weekday(year, 12, 31); /* days in the week */
- - if (fday < 4)
- - weeknum = 1;
- - }
- -
- - return weeknum;
- -
- -} /* weeknr */
- -/*************************************************************************
- - ** **
- - ** OTHER ROUTINES **
- - ** **
- - *************************************************************************/
- -
- -
- -
- -/*
- - * checkdate -- checks if the given date is a valid one.
- - * if not, it just exits.
- - */
- -void checkdate(year, month, day)
- -int year, month, day;
- -{
- - int dim;
- -
- - if (year < 0) {
- - fprintf(stderr, "%s: %d is an invalid year\n", progname, year);
- - exit(2);
- - }
- -
- - if ((month < 1) || (month > 12)) {
- - fprintf(stderr, "%s: %d is an invalid month\n", progname, month);
- - exit(2);
- - }
- -
- - dim = days[month];
- - if ((month == 2) && LEAP(year))
- - dim++;
- - if ((day > dim) || (day < 1)) {
- - fprintf(stderr, "%s: %d is an invalid day in %s %d\n", progname,
- - day, monthname[month], year);
- - exit(2);
- - }
- -
- - return;
- -
- -} /* checkdate */
- -
- -
- -
- -/*
- - * usage -- give usage message.
- - */
- -void usage()
- -{
- -
- - fprintf(stderr,"Usage: weekday [-svdDmMywjnah] [<date>]\n");
- - fprintf(stderr," <date>: mm/dd/yy dd-mm-yy yy.ddd Unix date\n");
- - fprintf(stderr," default is today\n");
- - fprintf(stderr," options: -s toggle short form output\n");
- - fprintf(stderr," -v toggle verbose output\n");
- - fprintf(stderr," -d prints day of week number\n");
- - fprintf(stderr," -D gives day of week name\n");
- - fprintf(stderr," -m prints the month number\n");
- - fprintf(stderr," -M outputs the month name\n");
- - fprintf(stderr," -y outputs the year number\n");
- - fprintf(stderr," -w gives the week number\n");
- - fprintf(stderr," -j outputs the julian day number\n");
- - fprintf(stderr," -n gives day of month\n");
- - fprintf(stderr," -a gives everything it knows (default)\n");
- - fprintf(stderr," -h give a usage message\n");
- -
- - return;
- -
- -} /* usage */
- _E_O_F_
- if test 26078 -ne `wc -c < weekday.c `; then
- echo shar: "'weekday.c'" unpacked with wrong size!
- fi
- # end of shell archive
- exit 0
- --
- #########################################
- # Marcel J.E. Mol ######################################
- # Delft University of Technology Pink Elephant Management Services #
- # The Netherlands Voorburg #
- # UUCP: marcel@duteca.tudelft.nl Tel: 070-694231 #
- # ######################################
- #########################################
-
-
- ----- End Forwarded Message -----
-
-